﻿using System.Reflection;
using System.Runtime.Loader;
using LDM.Framework.Conul;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyModel;
using LDM.Framework.Caches;
using Newtonsoft.Json.Serialization;
using Microsoft.Extensions.Hosting;

namespace LDM.Framework.Application;

/// <summary>
/// 
/// </summary>
public static class App
{


    private static AppSettings? _appSettings;

    /// <summary>
    /// 应用程序配置
    /// </summary>
    public static AppSettings AppSettings => _appSettings ??= GetOptions<AppSettings>() ?? new AppSettings();

    /// <summary>
    /// 有效程序集中的类型
    /// </summary>
    public static IEnumerable<Type> Types { get; }

    /// <summary>
    /// 配置对象
    /// </summary>
    public static IConfiguration Configuration;

    /// <summary>
    /// 扫描类型列表
    /// </summary>
    public static IEnumerable<Type> ScanTypes { get; set; }

    /// <summary>
    /// 构造函数
    /// </summary>
    static App()
    {
        ScanTypes = Assembly.GetEntryAssembly()?.GetTypes()?.Where(p => p.GetCustomAttribute<AppScanAttribute>() != null) ?? new List<Type>();

        var assemblies = DependencyContext.Default.RuntimeLibraries
           .Where(r => r.Type == "project" || r.Type == "package" && r.Name.StartsWith("LDM"))
           .Select(r => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(r.Name)))
           .ToHashSet();

        //程序集中的有效类型
        Types = assemblies.SelectMany(a => a.GetTypes().Where(t => t.IsPublic));

    }
    /// <summary>
    /// 配置应用程序
    /// </summary>
    /// <param name="hostBuilder"></param>
    public static void ConfigureApplication(IWebHostBuilder hostBuilder)
    {
        //Consul配置
        hostBuilder.AddConsulConfig();

        hostBuilder.ConfigureServices((hostContext, services) =>
        {
            // 静态化配置对象
            Configuration = hostContext.Configuration;

            services.Configure<AppSettings>(hostContext.Configuration);

            // 注册 HttpContextAccessor 服务
            services.AddHttpContextAccessor();

            // 添加框架核心服务
            AddFrameworkCoreService(services);

        });
        //支持命令行参数
        hostBuilder.ConfigureAppConfiguration((context, bulider) =>
        {
            bulider.AddCommandLine(Environment.GetCommandLineArgs());
        });

     
    }

    /// <summary>
    /// 添加框架核心服务
    /// </summary>
    /// <param name="services"></param>
    static void AddFrameworkCoreService(IServiceCollection services)
    {
        services.AddSwaggerDoc()
            .AddDependencyInjection()
            .AddExceptionHandling()
            .AddMicrosoftMemoryCache();  //添加缓存

        //设置json格式
        services.AddControllers().AddNewtonsoftJson(options =>
        {
            //设置JSON返回日期格式()
            options.SerializerSettings.ContractResolver = new DefaultContractResolver();
        });
    }
    /// <summary>
    /// 封装要操作的字符
    /// </summary>
    /// <param name="sections">节点配置</param>
    /// <returns></returns>
    public static string GetConfig(params string[] sections)
    {
        try
        {
            if (sections.Any())
            {
                return Configuration[string.Join(":", sections)];
            }
        }
        catch (Exception)
        {

        }
        return "";
    }

    /// <summary>
    /// 获取 TOptions
    /// </summary>
    /// <typeparam name="TOptions"></typeparam>
    /// <param name="sections"></param>
    /// <returns></returns>
    public static TOptions? GetOptions<TOptions>(params string[] sections)
    {
        if (sections.Length > 0)
        {
            return Configuration.GetSection(string.Join(":", sections)).Get<TOptions>(); ;
        }
        return Configuration.Get<TOptions>();
    }
}
